using FineCollection.Intf;




namespace FineCollection.Cont
{
    
    internal class ArrIterator<TT> : RIterator<TT>,
                                     System.Collections.Generic.IEnumerator<TT>,
                                     System.Collections.IEnumerator
    {
        private TT[] arr;
        private int offset;
        private int count;

        private int intIndex;
        private sbyte where;


        internal ArrIterator(TT[] arr, int offset, int count)
        {
            this.arr = arr;
            this.offset = offset;
            this.count = count;
        }


        internal ArrIterator(TT[] arr, int offset, int count, int intIndex, sbyte where)
        {
            this.arr = arr;
            this.offset = offset;
            this.count = count;
            this.intIndex = intIndex;
            this.where = where;
        }


        public void Reset()
        {
            intIndex = int.MinValue;
            where = -1;
        }

        public bool Next()
        {
            switch (where)
            {
                case -1:
                    if (count > 0)
                    {
                        where = 0;
                        intIndex = 0;
                    }
                    else
                    {
                        where = +1;
                        intIndex = int.MaxValue;
                    }
                    break;
                case 0:
                    if (intIndex < count - 1)
                    {
                        intIndex++;
                    }
                    else
                    {
                        where = +1;
                        intIndex = int.MaxValue;
                    }
                    break;
                case 1:
                    throw new OutOfCollectionException("Iterator reaches the end of collection.");
            }

            return where == 0;
        }


        /// <summary>
        /// Represents where the current position of the iterator.
        /// </summary>
        /// <remarks>
        /// Possible value:
        /// <list type="bullet">
        /// <item>-1: before the first item;</item>
        /// <item>0: at an item of the collection;</item>
        /// <item>+1: behind the last item.</item>
        /// </list>
        /// </remarks>
        public sbyte Where
        {
            get { return where; }
        }


        public ArrIterator<TT> Clone()
        {
            return new ArrIterator<TT>(arr, offset, count, intIndex, where);
        }

        RIterator<TT> RIterator<TT>.Clone()
        {
            return Clone();
        }

        /*
        WIterator<TT> WIterator<TT>.Clone()
        {
            return Clone();
        }
        */


        TT RIterator<TT>.Current
        {
            get { return arr[intIndex]; }
        }


        public TT Current
        {
            get { return arr[offset + intIndex]; }
            set { arr[offset + intIndex] = value; }
        }



        TT System.Collections.Generic.IEnumerator<TT>.Current
        {
            get { return arr[intIndex]; }
        }

        object System.Collections.IEnumerator.Current
        {
            get { return arr[intIndex]; }
        }

        bool System.Collections.IEnumerator.MoveNext()
        {
            if (Where < +1)
                return Next(); // shifts the iterator
            else
                return false;
        }


        public void Dispose() { }

    }


}